﻿using System.Collections.Generic;
using Gola.VN.Scb.Web.Common.Entities;
using Gola.VN.Scb.Web.Dal;

namespace Gola.VN.Scb.Web.Bll
{
    public class MainBiz
    {
        private static MainBiz _mainBiz;
        private CategoryBiz _categoryBiz;
        private LocationBiz _locationBiz;
        private ProductBiz _productBiz;
        private ProviderBiz _providerBiz;
        private SearchHistoryBiz _searchHistoryBiz;
        private SysInfoBiz _sysInfoBiz;

        private MainBiz()
        {
        }

        public void ResetData()
        {
            //su dung system infor de reload data cache
            _sysInfoBiz.InitializeData();

            if (_sysInfoBiz.GetSystemInfo() == 1)
            {
                //reset cache
                _mainBiz.InitliazeSystem();
                //update status
                _sysInfoBiz.UpdateSysInfo();
            }
        }

        public static MainBiz GetInstant()
        {
            if (_mainBiz == null)
            {
                _mainBiz = new MainBiz();
                MainDao mainDao = MainDao.GetInstant();

                _mainBiz._productBiz = new ProductBiz(mainDao);
                _mainBiz._categoryBiz = new CategoryBiz(mainDao);
                _mainBiz._providerBiz = new ProviderBiz(mainDao);
                _mainBiz._sysInfoBiz = new SysInfoBiz(mainDao);
                _mainBiz._locationBiz = new LocationBiz(mainDao);
                _mainBiz._searchHistoryBiz = new SearchHistoryBiz(mainDao);
               
                _mainBiz.InitliazeSystem();
            }

            return _mainBiz;
        }

        public void Execute(BizPackage package)
        {
            switch (package.Model)
            {
                case ModelType.Category:
                    CategoryExecute(package);
                    break;
                case ModelType.Customer:
                    CustomerExecute(package);
                    break;
                case ModelType.Product:
                    ProductExecute(package);
                    break;
                case ModelType.Provider:
                    ProviderExecute(package);
                    break;
                case ModelType.Search:
                    SearchExecute(package);
                    break;
                default:
                    break;
            }
        }

        private void SearchExecute(BizPackage package)
        {
            switch (package.Event)
            {
                case BizEvent.DoSearch:
                    package.Output = _searchHistoryBiz.DoSearch((string)package.MultiInput[0],
                                                                (int)package.MultiInput[1]);
                    break;
                case BizEvent.UpdateSearchHistory:
                    package.Output = _searchHistoryBiz.UpdateSearchHistory(package.Input as SearchHistoryEntity);
                    break;
                case BizEvent.GetSearchHistories:
                    package.Output = _searchHistoryBiz.GetSearchHistories((string)package.Input);
                    break;
                default:
                    break;
            }
        }

        private void ProductExecute(BizPackage package)
        {
            switch (package.Event)
            {
                case BizEvent.GetProductById:
                    package.Output = _productBiz.GetProductById((int)package.Input);
                    break;
                case BizEvent.GetProducts:
                    package.Output = _productBiz.GetProducts();
                    break;
                case BizEvent.GetProductsByTitle:
                    package.Output = _productBiz.GetProductsByTitle(package.Input as string);
                    break;
                case BizEvent.GetProductsByCategoryId:
                    bool orderByViewCount = false;
                    if (package.MultiInput.Count >= 2)
                    {
                        orderByViewCount = (bool)package.MultiInput[1];
                    }
                    package.Output = _productBiz.GetProductsByCategoryId((int)package.MultiInput[0], orderByViewCount);
                    break;
                case BizEvent.GetProductsByProviderIdAndCategoryName:
                    package.Output = _productBiz.GetProductsByProviderIdAndCategoryName(
                        package.MultiInput[0] as string, (int)package.MultiInput[1]);
                    break;
                case BizEvent.GetProductsByProductTitle:
                    package.Output = _productBiz.GetProductsByProductTitle(
                        (int)package.MultiInput[0], package.MultiInput[1] as string);
                    break;
                case BizEvent.GetOthersProductByTitle:
                    package.Output = _productBiz.GetOthersProductByTitle(package.MultiInput[0] as string,
                                                                         package.MultiInput[1] as List<int>,
                                                                         (int)package.MultiInput[2]);
                    break;
                case BizEvent.GetOthersProductByCategoryId:
                    package.Output = _productBiz.GetOthersProductByCategoryId(
                        (int)package.MultiInput[0], package.MultiInput[1] as List<int>, (int)package.MultiInput[2]);
                    break;
                case BizEvent.UpdateProductViewCount:
                    _productBiz.UpdateProductViewCount((int)package.Input);
                    break;
                case BizEvent.InsertProduct:
                    package.Output = _productBiz.InsertProduct(package.Input as ProductEntity);
                    break;
                case BizEvent.GetRandomCategory:
                    package.Output = _productBiz.GetRandomCategory();
                    break;
                case BizEvent.GetHostCategories:
                    package.Output = _productBiz.GetHostCategories();
                    break;
                default:
                    break;
            }
        }

        private void ProviderExecute(BizPackage package)
        {
            switch (package.Event)
            {
                case BizEvent.InsertProvider:
                    package.Output = _providerBiz.InsertProvider(package.Input as ProviderEntity);
                    break;
                case BizEvent.UpdateProvider:
                    package.Output = _providerBiz.UpdateProvider(package.Input as ProviderEntity);
                    break;
                case BizEvent.GetProviders:
                    package.Output = _providerBiz.GetAllProviders();
                    break;
                case BizEvent.GetProviderById:
                    package.Output = _providerBiz.GetProvider((int)package.Input);
                    break;
                case BizEvent.GetProviderByName:
                    package.Output = _providerBiz.GetProvider((string)package.Input);
                    break;
                default:
                    break;
            }
        }

        private void CategoryExecute(BizPackage package)
        {
            switch (package.Event)
            {
                case BizEvent.GetSubcategories:
                    package.Output = _categoryBiz.GetSubCategories((int)package.Input);
                    break;
                case BizEvent.GetNavigateData:
                    package.Output = _categoryBiz.GetNavigateData((int)package.Input);
                    break;
                case BizEvent.GetCategoryById:
                    package.Output = _categoryBiz.GetCategoryById((int)package.Input);
                    break;
                case BizEvent.GetChildCategories:
                    package.Output = _categoryBiz.GetChildCategories((int)package.Input);
                    break;
                case BizEvent.GetCategoryAsFlat:
                    package.Output = _categoryBiz.GetCategoriesAsFlat();
                    break;
                case BizEvent.GetCategoriesByProviderId:
                    package.Output = _categoryBiz.GetCategoriesByProviderId((int)package.Input);
                    break;
                case BizEvent.GetCategoryAsTree:
                    package.Output = _categoryBiz.GetCategoriesAsTree();
                    break;
                case BizEvent.GetSubCategoriesAsTree:
                    package.Output = _categoryBiz.GetSubCategoriesAsTree((int)package.Input);
                    break;
                case BizEvent.GetCloudCategory:
                    package.Output = _categoryBiz.GetCloudCategory((int)package.Input);
                    break;
                default:
                    break;
            }
        }

        private void CustomerExecute(BizPackage package)
        {
        }

        private void InitliazeSystem()
        {
            // 1. get all product
            _productBiz.InitializeData();

            // 2. get all category (flat format)
            _categoryBiz.InitializeData();

            // 3. get all provider
            _providerBiz.InitializeData();

            // 4. get sys info
            _sysInfoBiz.InitializeData();

            // 5. get all location
            _locationBiz.InitializeData();

            // 6. get all search history
            _searchHistoryBiz.InitializeData();
        }
    }
}